import time

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from functools import wraps
from config.constant import IMPLICITLY
from handle.handle_log import log



class Event(object):

    """
    基础元素封装
    """

    def __init__(self, driver):
        self.driver = driver
        self.messages = []
        self.driver.maximize_window()

    def click_event(self, *args):

        """
        点击事件封装
        :param args:
        :return:
        """
        # 设置显示等待
        # driver

        # 设置隐式等待
        self.driver.implicitly_wait(IMPLICITLY)
        # 点击事件
        try:
            self.driver.find_element(*args).click()
        except Exception as e:
            log.error(e)

    def send_keys_event(self, value=None, *args):
        """
        传值事件封装
        """
        # 设置显示等待
        # driver

        # 设置隐式等待
        self.driver.implicitly_wait(IMPLICITLY)
        # 传值事件
        try:
            self.driver.find_element(*args).send_keys(value)
        except Exception as e:
            log.error(e)

    def get_text_value_event(self, *args):
        """
        获取元素的text值封装
        """
        # 设置隐式等待
        self.driver.implicitly_wait(IMPLICITLY)
        # 获取text值事件
        try:
            # 返回text值
            return self.driver.find_element(*args).text
        except Exception as e:
            log.error(e)

    def find_elements(self, *args):

        """
        多单元素定位的重装
        :param args:
        :return:
        """
        # 设置显示等待
        # driver

        # 设置隐式等待
        self.driver.implicitly_wait(IMPLICITLY)
        try:
            # 返回定位对象
            return self.driver.find_elements(*args)
        except Exception as e:
            log.error(e)


    def to_iframe(self, ele):

        """
        进入iframe
        :param ele:
        :return:
        """
        self.driver.implicitly_wait(IMPLICITLY)
        try:
            # 进入iframe
            self.driver.switch_to.frame(ele)
        except Exception as e:
            log.error(e)

    def to_parentiframe(self):
        """
        回退到父iframe
        :return:
        """
        self.driver.implicitly_wait(20)
        self.driver.switch_to.parent_frame()

    def to_content(self):
        """
        回退到默认
        :return:
        """
        self.driver.implicitly_wait(20)
        self.driver.switch_to.default_content()

    def alert_accept(self):
        """
        切换弹窗并接受
        :return:
        """
        time.sleep(1)
        alert = self.driver.switch_to.alert
        text = alert.text
        alert.accept()
        return text

    def alert_dismiss(self):
        """
        切换弹窗
        :return:
        """
        time.sleep(1)
        alert = self.driver.switch_to.alert
        text = alert.text
        alert.dismiss()
        return text

    def alert_sendkey(self, string):
        """
        传值弹窗
        :param string:
        :return:
        """
        time.sleep(1)
        alert = self.driver.switch_to.alert
        alert.send_keys(string)
        alert.accept()

    def exe_script(self, string):
        """
        执行js脚本
        :param string:
        :return:
        """
        self.driver.execute_script(string)

    def swith_windows(self, num):
        """
        切换窗口
        :param num:
        :return:
        """
        handles = self.driver.window_handles
        self.driver.switch_to.window(handles[num])
        text = self.driver.title
        return text

    def check_message(self, timeout=3):
        """
        检查ElMessage错消息，检查当前的页面是否有错误消息
        :param timeout:
        :return:
        """
        detected_messages = []
        error_msg = self


    @property
    def driver_(self):
        """
        提供给外部使用的driver
        :return:
        """
        return self.driver

    def back(self):
        """
        回退
        :return:
        """
        self.driver.back()

    def forward(self):
        """
        前进
        :return:
        """
        self.driver.forword()

    def refresh(self):
        """
        刷新
        :return:
        """
        self.driver.refresh()

    def check_click(self, *args):
        """
        判断元素是否可点击
        :param args:
        :return:
        """
        self.driver.implicitly_wait(IMPLICITLY)
        ele = self.find_element(*args)
        if ele.is_enabled() == True:
            return ele
        else:
            log.error("元素不可点击")

    def open_url(self, url):
        """
        打开url
        :return:
        """
        return self.driver.get(url)

    def screenshot(self,name, path):
        """
        截图功能
        """
        self.driver.get_screenshot_as_file(path + f'{name}.png')



    def close(self):
        """
        关闭页面
        :return:
        """
        self.driver.close()

    def quit(self):
        """
        推出浏览器
        :return:
        """
        self.driver.quit()

    def check_messages(self, timeout=3):
        """检查当前页面是否有消息，返回检测到的消息列表"""
        detected_messages = []

        # 检查错误消息
        error_msg = self._get_message('error', timeout)
        if error_msg:
            detected_messages.append(('error', error_msg))

        # 检查成功消息
        # success_msg = self._get_message('success', timeout)
        # if success_msg:
        #     detected_messages.append(('success', success_msg))

        # 记录所有消息
        self.messages.extend(detected_messages)
        return detected_messages

    def _get_message(self, message_type, timeout):
        try:
            # 使用更精确的选择器，避免与其他元素冲突
            message = WebDriverWait(self.driver, timeout).until(
                EC.visibility_of_element_located(
                    (By.XPATH,
                     f"//div[contains(@class, 'el-message') and contains(@class, 'el-message--{message_type}')]")
                )
            )
            content = message.find_element(By.XPATH, ".//p[contains(@class, 'el-message__content')]").text
            return content
        except:
            return None

    def clear_messages(self):
        """清空消息记录"""
        self.messages = []

    def get_all_messages(self):
        """获取所有记录的消息"""
        return self.messages

    def watch_page_load(self):
        """监控页面加载后自动检查消息"""
        self.check_messages()

    def action_listener(self, func):
        """装饰器：在函数执行后自动检查消息"""

        @wraps(func)
        def wrapper(*args, **kwargs):
            result = func(*args, **kwargs)
            time.sleep(0.5)  # 等待可能的异步操作
            self.check_messages()
            return result

        return wrapper


